package kontrol;

import view.ViewHUD;
import view.ViewViewPort;
import model.interfaces.selectable.ControllablePlayer;
import model.interfaces.selectable.SelectableRallyPoint;
import model.interfaces.selectable.SelectableGroup;
import model.interfaces.selectable.SelectableType;
import model.interfaces.selectable.SelectableInstance;
import model.interfaces.selectable.SelectableCommand;
import model.interfaces.commandTypes.ArgumentsVisitor;
import java.util.List;
import java.util.ArrayList;

/**
 *
 * @author kagioglu
 */
public class ViewportManager
{
    private ControllablePlayer cplayer;
    private ViewHUD hud;
    private ViewViewPort viewport;
    private Wheel<SelectableGroup> groupwheel;
    private Wheel<SelectableType> typewheel;
    private Wheel<SelectableInstance> instancewheel;
    private Wheel<SelectableCommand> commandwheel;
    private List<Integer> arglist;

    public ViewportManager
    (
        ControllablePlayer cplayer,
        ViewHUD hud,
        ViewViewPort viewport
    )
    {
        this.cplayer = cplayer;
        this.hud = hud;
        this.viewport = viewport;
        this.arglist = new ArrayList<Integer>();

        this.groupwheel =
            new Wheel<SelectableGroup>(null, new SelectableGroup[] {});
        this.typewheel =
            new Wheel<SelectableType>(null, new SelectableType[] {});
        this.instancewheel =
            new Wheel<SelectableInstance>(null, new SelectableInstance[] {});
        this.commandwheel =
            new Wheel<SelectableCommand>(null, new SelectableCommand[] {});

        this.resetGroupWheel();
    }

    public void scrollGroupUp()
    {
        this.groupwheel.increment();
        this.postGroup();
        this.resetTypeWheel();
        this.arglist.clear();
    }

    public void scrollGroupDown()
    {
        this.groupwheel.decrement();
        this.postGroup();
        this.resetTypeWheel();
        this.arglist.clear();
    }

    public void scrollTypeUp()
    {
        this.typewheel.increment();
        this.postType();
        this.resetInstanceWheel();
        this.arglist.clear();
    }

    public void scrollTypeDown()
    {
        this.typewheel.decrement();
        this.postType();
        this.resetInstanceWheel();
        this.arglist.clear();
    }

    public void scrollInstanceUp()
    {
        this.instancewheel.increment();
        this.postInstance();
        this.resetCommandWheel();
        this.arglist.clear();
    }

    public void scrollInstanceDown()
    {
        this.instancewheel.decrement();
        this.postInstance();
        this.resetCommandWheel();
        this.arglist.clear();
    }

    public void scrollCommandUp()
    {
        this.commandwheel.increment();
        this.postCommand();
        this.arglist.clear();
    }

    public void scrollCommandDown()
    {
        this.commandwheel.decrement();
        this.postCommand();
        this.arglist.clear();
    }

    public void setArg( int code )
    {
        this.arglist.add(code);
        Integer[] temp = this.arglist.toArray(new Integer[this.arglist.size()]);
        ArgumentsVisitor visitor = new ArgVisitor(temp, this.viewport);
        this.commandwheel.getSelection().accept(visitor);
    }

    public void addCommand()
    {
        if
        (
            this.instancewheel.getSelection() != null &&
            this.commandwheel.getSelection() != null
        )
        {
            this.instancewheel.getSelection().
                addCommandToQueue(this.commandwheel.getSelection());
        }
        this.arglist.clear();
    }

    public void centerOnSelectedInstance()
    {
        SelectableInstance temp = this.instancewheel.getSelection();
        if(temp != null)
        {
            this.viewport.center(this.cplayer.getInstLocation(temp).getPoint());
        }
    }

    public void createNewRallyPoint( int newID )
    {
        SelectableRallyPoint[] rps = this.cplayer.getRallyPoints();
        boolean alreadyExists = false;
        for(SelectableRallyPoint rp : rps)
        {
            alreadyExists = alreadyExists || (rp.getID() == newID);
        }
        if(!alreadyExists) this.cplayer.createRallyPoint(newID);
    }

    public void refresh()
    {
        this.resetGroupWheel();
    }

    private void resetGroupWheel()
    {
        SelectableGroup[] temp = new SelectableGroup[0];
        if(this.cplayer != null)
        {
            temp = this.cplayer.getGroups();
        }
        this.groupwheel = new Wheel<SelectableGroup>
        (
            this.groupwheel.getSelection(),
            temp
        );

        this.postGroup();
        this.resetTypeWheel();
    }

    private void postGroup()
    {
        String name = "";
        if(this.groupwheel.getSelection() != null)
        {
            name = this.groupwheel.getSelection().getName();
        }
        this.hud.setGroupBox(name);
    }

    private void resetTypeWheel()
    {
        SelectableType[] temp = new SelectableType[0];
        if(this.groupwheel.getSelection() != null)
        {
            temp = this.groupwheel.getSelection().getTypes();
        }
        this.typewheel = new Wheel<SelectableType>
        (
            this.typewheel.getSelection(),
            temp
        );

        this.postType();
        this.resetInstanceWheel();
    }

    private void postType()
    {
        String name = "";
        if(this.typewheel.getSelection() != null)
        {
            name = this.typewheel.getSelection().getName();
        }
        this.hud.setTypeBox(name);
    }

    private void resetInstanceWheel()
    {
        SelectableInstance[] temp = new SelectableInstance[0];
        if(this.typewheel.getSelection() != null)
        {
            temp = this.typewheel.getSelection().getInstances();
        }
        this.instancewheel = new Wheel<SelectableInstance>
        (
            this.instancewheel.getSelection(),
            temp
        );

        this.postInstance();
        this.resetCommandWheel();
    }

    private void postInstance()
    {
        String name = "";
        if(this.instancewheel.getSelection() != null)
        {
            SelectableInstance si = this.instancewheel.getSelection();
            name = si.getName();
            this.hud.setStatusOverview(si.getStatus());
        }
        this.hud.setInstanceBox(name);
    }

    private void resetCommandWheel()
    {
        SelectableCommand[] temp = new SelectableCommand[0];
        if(this.instancewheel.getSelection() != null)
        {
            temp = this.instancewheel.getSelection().getCommands();
        }
        this.commandwheel = new Wheel<SelectableCommand>
        (
            this.commandwheel.getSelection(),
            temp
        );

        this.postCommand();
    }

    private void postCommand()
    {
        String name = "";
        if(this.commandwheel.getSelection() != null)
        {
            name = this.commandwheel.getSelection().getName();
        }
        this.hud.setCommandBox(name);
    }
}
